/**
 * 
 */
package com.maywide.jdp.system.bean;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.maywide.jdp.core.exception.AppException;
import com.maywide.jdp.core.vo.Page;
import com.maywide.jdp.dao.Dao;
import com.maywide.jdp.dao.PageQueryTemplate;
import com.maywide.jdp.dao.QueryTemplate;
import com.maywide.jdp.system.entities.Operator;
import com.maywide.jdp.system.entities.Organization;
import com.maywide.jdp.system.entities.Role;

/**
 * 操作员管理Bean
 * 
 * @author luoyang
 * @version 1.0
 * @since JDK1.6
 */
@Component("operatorBean")
@Transactional(propagation = Propagation.REQUIRED)
public class OperatorBeanImpl implements OperatorBean {
	/**
	 * 基础DAO
	 */
	private Dao dao = null;

	/**
	 * @param dao
	 *            the dao to set
	 */
	@Autowired
	public void setDao(Dao dao) {
		this.dao = dao;
	}

	@Override
	public void insert(Object obj) throws Exception {
		dao.insert(obj);
	}

	@Override
	public void update(Object obj) throws Exception {
		dao.update(obj);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public void remove(Class clazz, Serializable id) throws Exception {
		Object obj = dao.find(clazz, id);
		dao.remove(obj);
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Object load(Serializable id) throws Exception {
		Operator operator = dao.find(Operator.class, id);
		return operator;
	}

	@Override
	public void lock(String id) throws Exception {
		String jql = "update Operator as o set o.active = false where o.id = :id";
		Query query = dao.createQuery(jql);
		query.setParameter("id", id);
		query.executeUpdate();
	}

	@Override
	public void lockAll(String[] ids) throws Exception {
		String hql = "update Operator as o set o.active = false where o.id in (:ids)";
		Map<String, Object> conditions = new HashMap<String, Object>();
		conditions.put("ids", ids);
		dao.executeUpdate(hql, conditions);
	}

	@Override
	public void unlock(String id) throws Exception {
		String jql = "update Operator as o set o.active = true where o.id = :id";
		Query query = dao.createQuery(jql);
		query.setParameter("id", id);
		query.executeUpdate();
	}

	@Override
	public void unlockAll(String[] ids) throws Exception {
		String hql = "update Operator as o set o.active = true where o.id in (:ids)";
		Map<String, Object> conditions = new HashMap<String, Object>();
		conditions.put("ids", ids);
		dao.executeUpdate(hql, conditions);
	}

	@Override
	public void move(String id, String oldOrgID, String newOrgID)
			throws Exception {
		String sql = "UPDATE SYS_ORGANIZATION_OPERATOR_REL SET ORG_ID = :newOrgID WHERE OPER_ID = :id AND ORG_ID = :oldOrgID";
		Query query = dao.createQuery(sql);
		int row = 0;
		query.setParameter("id", id);
		query.setParameter("oldOrgID", oldOrgID);
		query.setParameter("newOrgID", newOrgID);
		row = query.executeUpdate();
		if (row <= 0)
			throw new AppException("未发生移动操作!");
	}

	@Override
	public void move(List<String> ids, String oldOrgID, String newOrgID)
			throws Exception {
		int row = 0;
		String sql = "UPDATE SYS_ORGANIZATION_OPERATOR_REL SET ORG_ID = :newOrgID WHERE OPER_ID in (:ids) AND ORG_ID = :oldOrgID";
		Query query = dao.createNativeQuery(sql);
		query.setParameter("ids", ids);
		query.setParameter("oldOrgID", oldOrgID);
		query.setParameter("newOrgID", newOrgID);
		row = query.executeUpdate();
		if (row <= 0)
			throw new AppException("未发生移动操作!");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.maywide.jdp.system.operator.bean.IOperatorBean#findByOperatorID(java
	 * .lang.String)
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Operator findByOperatorID(String operatorID) throws Exception {
		String jql = "from Operator as o where o.operatorID=:operatorID";
		Map<String, Object> parameters = new HashMap<String, Object>();
		parameters.put("operatorID", operatorID);
		Query query = dao.createQuery(jql);
		query.setParameter("operatorID", operatorID);
		Operator operator = (Operator) query.getSingleResult();

		// 不再惰性取出，而是直接取出
		if (operator != null) {
			List<Role> roles = operator.getRoles();
			if (roles != null && !roles.isEmpty()) {
				for (Role role : roles) {
					role.getId();
				}
			}
			List<Organization> organizations = operator.getOrganizations();
			if (organizations != null && !organizations.isEmpty()) {
				for (Organization organization : organizations) {
					organization.getId();
				}
			}
		}
		return operator;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Operator> list(String sort, String dir,
			Map<String, Object> conditions, Map<String, Object> parameters)
			throws Exception {
		List list = null;
		String queryString = null;

		if (conditions.containsKey("organizationID"))
			queryString = "select distinct o from Operator as o inner join o.organizations as org";
		else if (conditions.containsKey("roleID"))
			queryString = "select distinct o from Operator as o inner join o.roles as r";

		QueryTemplate template = new QueryTemplate(queryString, sort, dir);
		list = dao.executeListQuery(template, conditions, parameters);
		return list;
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Page page(int first, int limit, String sort, String dir,
			Map<String, Object> conditions, Map<String, Object> parameters)
			throws Exception {
		Page page = null;

		String queryString = "select distinct o from Operator as o left join o.organizations as org where org.id is null";
		String countQueryString = "select count(distinct o.id) from Operator as o left join o.organizations as org where org.id is null ";
		if (conditions.containsKey("organizationID")) {
			queryString = "select distinct o from Operator as o inner join o.organizations as org";
			countQueryString = "select count(distinct o.id) from Operator as o inner join o.organizations as org";
		}
		PageQueryTemplate template = new PageQueryTemplate(queryString,
				countQueryString, first, limit, sort, dir);
		page = dao.executePageQuery(template, conditions, parameters);

		return page;
	}

}
